[PATCH] udev: check for invalid chars in various fields received from the kernel
authorLuca Boccassi <luca.boccassi@gmail.com>
Fri, 6 Mar 2026 19:32:35 +0000 (19:32 +0000)
committerArnaud Rebillout <arnaudr@debian.org>
Mon, 13 Apr 2026 07:18:40 +0000 (14:18 +0700)
(cherry picked from commit 16325b35fa6ecb25f66534a562583ce3b96d52f3)
(cherry picked from commit 3513862eabe9ec4a6a095d7266e98f998f289ed2)
(cherry picked from commit c20d21e0da293e715db468f9f4a15a5c8fbf8273)

Origin: backport, https://github.com/systemd/systemd/commit/03bb697b8df0339c37f4b845025320b261aeb7cc

Gbp-Pq: Name CVE-2026-40225.patch

src/udev/scsi_id/scsi_id.c
src/udev/udev-builtin-net_id.c
src/udev/v4l_id/v4l_id.c

index 57202564da5c155221689fd29ecb530f773b54ff..72e4ee401c40edbf29521bcee7fb7a254d7cf6c8 100644 (file)
@@ -24,6 +24,7 @@
 #include "string-util.h"
 #include "strxcpyx.h"
 #include "udev-util.h"
+#include "utf8.h"
 
 static const struct option options[] = {
         { "device",             required_argument, NULL, 'd' },
@@ -519,7 +520,7 @@ static int scsi_id(char *maj_min_dev) {
                 }
                 if (dev_scsi.tgpt_group[0] != '\0')
                         printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group);
-                if (dev_scsi.unit_serial_number[0] != '\0')
+                if (dev_scsi.unit_serial_number[0] != '\0' && utf8_is_valid(dev_scsi.unit_serial_number) && !string_has_cc(dev_scsi.unit_serial_number, /* ok= */ NULL))
                         printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number);
                 goto out;
         }
index d06a8c71560dd3436d0612a0624a8e3299f2ebc8..1da16dad2137bd1721d65fbcc557a3a3f7379896 100644 (file)
@@ -35,6 +35,7 @@
 #include "strv.h"
 #include "strxcpyx.h"
 #include "udev-builtin.h"
+#include "utf8.h"
 
 #define ONBOARD_INDEX_MAX (16*1024-1)
 
@@ -198,6 +199,9 @@ static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
         /* kernel provided front panel port name for multiple port PCI device */
         (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name);
 
+        if (port_name && (!utf8_is_valid(port_name) || string_has_cc(port_name, /* ok= */ NULL)))
+                port_name = NULL;
+
         s = names->pci_onboard;
         l = sizeof(names->pci_onboard);
         l = strpcpyf(&s, l, "o%lu", idx);
@@ -210,6 +214,8 @@ static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
 
         if (sd_device_get_sysattr_value(names->pcidev, "label", &names->pci_onboard_label) < 0)
                 names->pci_onboard_label = NULL;
+        else if (!utf8_is_valid(names->pci_onboard_label) || string_has_cc(names->pci_onboard_label, /* ok= */ NULL))
+                names->pci_onboard_label = NULL;
 
         return 0;
 }
@@ -310,6 +316,9 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
         /* kernel provided front panel port name for multi-port PCI device */
         (void) sd_device_get_sysattr_value(dev, "phys_port_name", &port_name);
 
+        if (port_name && (!utf8_is_valid(port_name) || string_has_cc(port_name, /* ok= */ NULL)))
+                port_name = NULL;
+
         /* compose a name based on the raw kernel's PCI bus, slot numbers */
         s = names->pci_path;
         l = sizeof(names->pci_path);
@@ -773,6 +782,9 @@ static int names_netdevsim(sd_device *dev, struct netnames *names) {
         if (r < 0)
                 return r;
 
+        if (!utf8_is_valid(port_name) || string_has_cc(port_name, /* ok= */ NULL))
+                return -EINVAL;
+
         ok = snprintf_ok(names->netdevsim_path, sizeof(names->netdevsim_path), "i%un%s", addr, port_name);
         if (!ok)
                 return -ENOBUFS;
index 932446b766dadfef611c5d6b3f09d735531490fd..102992270b4fd8c7a2ab514730737e4fc8c12755 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "fd-util.h"
 #include "util.h"
+#include "string-util.h"
+#include "utf8.h"
 
 int main(int argc, char *argv[]) {
         static const struct option options[] = {
@@ -66,7 +68,8 @@ int main(int argc, char *argv[]) {
         if (ioctl(fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
                 int capabilities;
                 printf("ID_V4L_VERSION=2\n");
-                printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
+                if (utf8_is_valid((char *)v2cap.card) && !string_has_cc((char *)v2cap.card, /* ok= */ NULL))
+                        printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
                 printf("ID_V4L_CAPABILITIES=:");
                 if (v2cap.capabilities & V4L2_CAP_DEVICE_CAPS)
                         capabilities = v2cap.device_caps;